home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-01-25 | 85.9 KB | 2,674 lines | [TEXT/KAHL] |
- /* os_mac_eEdit.c
- * 8Apr92 e
- */
-
- #include <MacHeaders>
-
- #include "os_mac_eEdit.h"
-
- /* an editor for text files by e
- questions/comments via Internet <e@Flavors.COM> */
- /* Copyright © e, 1992. All rights reserved.
- Developed using THINK C 5.0.1 for use with Gambit Scheme.
- This code may be freely distributed as long as this notice remains.
- based upon CEditor.C...
- Copyright © BRH Toolsmith, 1992. All rights reserved.
- Developed using THINK C 4.0.2 and Symantec's OOP libraries.
- Portions of this code nd )
- { c = *p++;
- if ( c < ' ' )
- { if ( c == '\r' )
- { line_count++;
- *q++ = c;
- start = q;
- }
- else if ( c == '\t' )
- { c = tabstop - ( ( q - start ) % tabstop);
- *q++ = c;
- c -= 1;
- start -= c;
- new_size += c;
- }
- else if ( p == end )
- { *q++ = lastch; /* the last char may be a control char */
- }
- else
- { old_size -= 1;
- new_size -= 1;
- }
- }
- else
- *q++ = c;
- }
- *count = line_count;
- *size = new_size;
- SetHandleSize( h, new_size );
- asm { move.w D0, error } /* error = MemError(); */
- if ( error == noErr )
- { end = *(unsigned char **)h;
- p = &end[new_size];
- *--p = lastch;
- start = &end[old_size-1];
- while ( p > end )
- { c = *--start;
- if ( c < ' ' && c != '\r' )
- while ( c-- ) *--p = ' ';
- else
- *--p = c;
- }
- }
- else
- { /* cleanup the buffer? */
- }
- return error;
- }
-
- static void undoBugNi( eRec **hE )
- { SysBeep(3); SysBeep(10); SysBeep(3);
- }
-
- void eTeInit( void )
- {
- gUtilRgn = NewRgn();
- gClicks = 0;
- /* 13Aug92 e */
- eTeScrap = NewHandle(0);
- eTeScrapLen = 0;
- eTeScrapCnt = (InfoScrap())->scrapCount - 1;
- eTeGetScrap();
- /* */
- eTeUndoStuff.undoProc = undoBugNi;
- eTeUndoStuff.undoTitle = utUndo;
- eTeUndoStuff.undoText = NewHandle(0);
- eTeUndoStuff.undoTeRec = NULL;
- }
-
- /* replacement can be installed via eTeSetWordBreak() */
-
- #if 0
- static long WordLimits( char *text, long offset, Boolean reverse )
- {
- register char *ptr, c;
-
- ptr = text + offset;
- if ( reverse ) {
- /* Scan backwards until we find beginning of word */
- while ( ptr > text ) {
- c = *( ptr - 1 );
- if ( ( c >= 'a' && c <= 'z' ) ||
- ( c >= 'A' && c <= 'Z' ) ||
- ( c >= '0' && c <= '9' ) ||
- ( c == '_' ) )
- --ptr;
- else
- break;
- }
- }
- else {
- /* Scan forwards until we find end of word */
- while ( 1 ) {
- c = *ptr;
- if ( ( c >= 'a' && c <= 'z' ) ||
- ( c >= 'A' && c <= 'Z' ) ||
- ( c >= '0' && c <= '9' ) ||
- ( c == '_' ) )
- ++ptr;
- else
- break;
- }
- }
- return( ptr - text );
- }
- #else
- static long WordLimits( char *text, long offset, Boolean reverse )
- {
- register char *ptr, c;
-
- ptr = text + offset;
- if ( reverse ) {
- /* Scan backwards until we find beginning of word */
- while ( ptr > text ) {
- c = *( ptr - 1 );
- if ( !( ( c >= 0 && c <= 32 ) ||
- ( c == '(' ) || ( c == ')' ) ||
- ( c == ';' ) || ( c == '"' ) ) )
- --ptr;
- else
- break;
- }
- }
- else {
- /* Scan forwards until we find end of word */
- while ( 1 ) {
- c = *ptr;
- if ( !( ( c >= 0 && c <= 32 ) ||
- ( c == '(' ) || ( c == ')' ) ||
- ( c == ';' ) || ( c == '"' ) ) )
- ++ptr;
- else
- break;
- }
- }
- return( ptr - text );
- }
- #endif
-
- static short eTeNewRuns( eRec **hE, long len )
- { register long *runPtr;
- register eRec *pE;
- short error;
-
- if ( (**hE).hRuns )
- DisposHandle( (Handle )(**hE).hRuns );
- (**hE).hRuns = (long **)NewHandle( MIN_RUNS * sizeof( long ) );
- asm { move.w D0, error } /* error = MemError(); */
- if( error == noErr )
- { pE = *hE;
- runPtr = *((*pE).hRuns);
- *runPtr++ = 0L;
- *runPtr = len;
- (*pE).runsAllocated = MIN_RUNS;
- (*pE).qRuns = 1;
- (*pE).fustStyle = 0;
- }
- return error;
- }
-
- long eTeTextLength( eRec **hE )
- {
- return (*(**hE).hRuns)[(**hE).qRuns];
- }
-
- eRec **eTeNew( WindowPtr macPort, Rect viewRect, short tabStops, short wrap,
- short autoInd, ControlHandle aHSizing, ControlHandle aVSizing )
- {
- register eRec *pE;
- LineRec *linePtr;
- eRec **hE = (eRec **)NewHandle( sizeof( eRec ) );
-
- if( hE != 0 )
- { HLock( (Handle )hE );
- pE = *hE;
- (*pE).active = FALSE;
- (*pE).macPort = macPort;
- (*pE).viewRect = viewRect;
- (*pE).width = viewRect.right - viewRect.left;
- (*pE).height = viewRect.bottom - viewRect.top;
- (*pE).hOrigin = -viewRect.left;
- (*pE).vOrigin = -viewRect.top;
- (*pE).position.h = (*pE).position.v = 0;
- (*pE).hScale = (*pE).vScale = 1;
- (*pE).bounds.v = 1;
- (*pE).bounds.h = 1; /* arbitrary size for now */
- (*pE).leftMargin = 1; /* room for cursor will blink at the far left */
- (*pE).topMargin = 0;
- (*pE).selStart.h = (*pE).selStart.v = 0;
- (*pE).selEnd = (*pE).selStart;
- (*pE).selActive = FALSE;
- (*pE).caretChPos.h = (*pE).caretChPos.v = 0;
- (*pE).writeChPos.h = (*pE).writeChPos.v = 0;
- (*pE).caretState = CARET_OFF;
- (*pE).maxRight = 0;
- (*pE).eTeWordBreak = WordLimits;
- SetPort( macPort );
- (*pE).tabStops = tabStops;
- (*pE).spaceWidth = 1;
- (*pE).wrap = wrap; /* 5Jul92 e */
- (*pE).autoInd = autoInd;
- (*pE).hText = NewHandle( 1L );
- **((*pE).hText) = '\0';
- (*pE).hLines = (LineRec **)NewHandle( MIN_LINES * sizeof( LineRec ) );
- linePtr = *((*pE).hLines);
- *linePtr++ = 0L;
- *linePtr = 0L;
- (*pE).linesAllocated = MIN_LINES;
- /* 2May92 e */
- (*pE).hRuns = NULL;
- eTeNewRuns( hE, 0L);
- (*pE).qRuns = 0;
- (*pE).hPrint = NULL; /* 28Sep92 e */
- /* scrollPane */
- (*pE).hStep = (*pE).vStep = 1;
- (*pE).hOverlap = (*pE).vOverlap = 1;
- (*pE).hContext = (*pE).vContext = CONTEXT_LINES;
- if ( ( (*pE).hSBar = aHSizing ) != NULL )
- { SetCRefCon( aHSizing, (long )hE );
- SetCtlAction( aHSizing, hSBarActionProc );
- /* SetThumbFunc( aHSizing, SBarThumbFunc ); */
- }
- if ( ( (*pE).vSBar = aVSizing ) != NULL )
- { SetCRefCon( aVSizing, (long )hE );
- SetCtlAction( aVSizing, vSBarActionProc );
- /* SetThumbFunc( aVSizing, SBarThumbFunc ); */
- }
- HUnlock( (Handle )hE );
- eTeSetStyles( hE, &dfltStylNormal, &dfltStylHilite);
- eTeAdjustScrollMax( hE );
- eTeCalibrate( hE );
- (**hE).dirty = FALSE; /* was (*pE). 14Jul92 e */
- (**hE).active = TRUE; /* was (*pE). 14Jul92 e */
- }
- return hE;
- }
-
- void eTeDispose( eRec **hE )
- {
- if ( (**hE).hText )
- DisposHandle( (**hE).hText );
- (**hE).hText = NULL;
- if ( (**hE).hLines )
- DisposHandle( (Handle )(**hE).hLines );
- (**hE).hLines = NULL;
- if ( (**hE).hRuns )
- DisposHandle( (Handle )(**hE).hRuns );
- (**hE).hRuns = NULL;
- if ( (**hE).hPrint )
- DisposHandle( (Handle)(**hE).hPrint ); /* 28Sep92 e */
- DisposHandle( (Handle )hE );
- }
-
- static void eTePrepare( eRec **hE )
- {
- Rect tempRect; /* ClipRect may move memory */
-
- SetPort( (**hE).macPort );
- tempRect = (**hE).viewRect;
- ClipRect(&tempRect);
- /* obsolete...
- TextFont( (**hE).fontNumber );
- TextSize( (**hE).fontSize );
- TextFace( 0 ); */
- /* Paranoid... */
- TextMode( srcOr );
- }
-
- static void eTePrepareStyle( eRec **hE, short style )
- {
- if( (**hE).curStyle != style )
- { (**hE).curStyle = style;
- TextFont( (**hE).style[style].tsFont );
- TextFace( (**hE).style[style].tsFace );
- TextSize( (**hE).style[style].tsSize );
- /* RGBColor tsColor; */
- }
- }
-
- static void eTePrepareRun( eRec **hE, short run )
- {
- eTePrepareStyle( hE, eTeRunToStyle( hE, run ) );
- }
-
- static void eTeRefresh( eRec **hE )
- {
- SetPort( (**hE).macPort );
- InvalRect( &(**hE).viewRect );
- }
-
- static void eTeUpdateCaretRect( eRec **hE )
- {
- Point tempPt;
- register eRec *pE;
-
- tempPt = eTeChPosToPoint( hE, (**hE).caretChPos );
- pE = *hE;
- (*pE).caretRect.top = tempPt.v;
- (*pE).caretRect.right = tempPt.h;
- (*pE).caretRect.left = tempPt.h - 1;
- (*pE).caretRect.bottom = tempPt.v + (*pE).caretHeight;
- }
-
- void eTeSetWrap( eRec **hE, short wrap )
- {
- /* 22Jul92 e -- added limits */
- if( wrap < 1 ) wrap = 1;
- else if( wrap > 999 ) wrap = 999;
- /* (**hE).wrap = wrap; */
- /* 10Aug92 e need to fix all ChPos for new wrap! */
- if( (**hE).wrap != wrap )
- { long car = eTeChPosToOffset( hE, (**hE).caretChPos );
- long sta = eTeChPosToOffset( hE, (**hE).selStart );
- long end = eTeChPosToOffset( hE, (**hE).selEnd );
- long wri = eTeChPosToOffset( hE, (**hE).writeChPos );
- (**hE).wrap = wrap;
- eTeUpdateLineStarts( hE, 0 );
- (**hE).caretChPos = eTeOffsetToChPos( hE, car );
- (**hE).selStart = eTeOffsetToChPos( hE, sta );
- (**hE).selEnd = eTeOffsetToChPos( hE, end );
- (**hE).writeChPos = eTeOffsetToChPos( hE, wri );
- eTeUpdateCaretRect( hE );
- eTeRefresh( hE );
- }
- }
-
- void eTeSetTabStop( eRec **hE, short aTabStop )
- {
- /* Undo? */
- (**hE).tabStops = aTabStop;
- (**hE).tabWidth = aTabStop * (**hE).spaceWidth;
- eTeRefresh( hE );
- }
-
- static short eTeTabStop( eRec **hE, register short curPosition )
- {
- register short tabWidth = (**hE).tabWidth;
- return (curPosition +
- (tabWidth -
- ((curPosition - (**hE).leftMargin + (**hE).hOrigin) % tabWidth)));
- }
-
- void eTeSetWordBreak( eRec **hE, ProcPtr aFunc )
- {
- if ( aFunc == NULL )
- (**hE).eTeWordBreak = WordLimits;
- else
- (**hE).eTeWordBreak = aFunc;
- }
-
- /* 23Jul92 e */
-
- /* Inverts the text between the start and stop positions. */
-
- static void eTeHiliteRange( eRec **hE, register ChPos start, register ChPos stop )
- {
- Rect tmpRect;
- Point stopPt;
- register short vScale;
-
- if ( ! (**hE).active )
- return;
-
- topLeft( tmpRect ) = eTeChPosToPoint( hE, start );
- tmpRect.left -= 1;
-
- vScale = (**hE).vScale;
-
- /* Just need to hilite within same line */
- if ( start.v == stop.v ) {
- botRight( tmpRect ) = eTeChPosToPoint( hE, stop );
- tmpRect.right -= 1;
- tmpRect.bottom = tmpRect.top + vScale;
- if ( tmpRect.left != tmpRect.right ) {
- eTePrepare( hE );
- asm { bclr #hiliteBit, HiliteMode }
- InvertRect( &tmpRect );
- }
- }
- /* Hilite spans more than one line */
- else
- { stopPt = eTeChPosToPoint( hE, stop );
- if( tmpRect.top < (**hE).viewRect.bottom && stopPt.v >= (**hE).viewRect.top )
- { eTePrepare( hE );
- tmpRect.right = (**hE).viewRect.right;
- tmpRect.bottom = tmpRect.top + vScale;
- if( tmpRect.bottom > (**hE).viewRect.top )
- { asm { bclr #hiliteBit, HiliteMode }
- InvertRect( &tmpRect );
- tmpRect.top += vScale;
- }
- else
- tmpRect.top = (**hE).viewRect.top;
- tmpRect.left = (**hE).viewRect.left;
- tmpRect.bottom = Min( stopPt.v, (**hE).viewRect.bottom );
- asm { bclr #hiliteBit, HiliteMode }
- InvertRect( &tmpRect );
- if( stopPt.v < (**hE).viewRect.bottom )
- { tmpRect.bottom += vScale;
- tmpRect.top = stopPt.v;
- tmpRect.right = stopPt.h - 1;
- asm { bclr #hiliteBit, HiliteMode }
- InvertRect( &tmpRect );
- }
- }
- }
- }
-
- /* 23Jul92 e */
-
- static void eTeSetCaretState( eRec **hE, Boolean state )
- {
- Rect tmpRect;
- register eRec *pE = *hE;
-
- if ( ! (*pE).selActive
- && (*pE).active
- && (*pE).caretState != state )
- {
- (*pE).caretState = state;
- tmpRect = (*pE).caretRect;
- eTePrepare( hE );
- PenMode(patXor);
- FrameRect( &tmpRect );
- PenNormal();
- }
- }
-
- void eTeActivate( eRec **hE )
- {
- if( (**hE).active == FALSE )
- { (**hE).active = TRUE;
- if( (**hE).selActive )
- eTeHiliteRange( hE, (**hE).selStart, (**hE).selEnd );
- }
- }
-
- void eTeDeactivate( eRec **hE )
- {
- if( (**hE).active == TRUE )
- { if( (**hE).selActive )
- eTeHiliteRange( hE, (**hE).selStart, (**hE).selEnd );
- else
- eTeSetCaretState( hE, CARET_OFF );
- (**hE).active = FALSE;
- }
- }
-
- void eTeIdle( eRec **hE )
- {
- static long lastCaretToggle = 0L;
- register long now;
- Rect tmpRect;
-
- gMaxSleep = GetCaretTime(); /* user may change it using desk accessory */
- now = TickCount();
- if ( now - lastCaretToggle >= gMaxSleep ) {
- lastCaretToggle = now;
- eTeSetCaretState( hE, (**hE).caretState == CARET_OFF ? CARET_ON : CARET_OFF );
- }
- else {
- gMaxSleep -= ( now - lastCaretToggle );
- }
- }
-
- static void eTeResize( eRec **hE, register Rect *delta )
- {
- register eRec *pE = *hE;
-
- (*pE).width += delta->right - delta->left;
- (*pE).height += delta->bottom - delta->top;
- (*pE).leftMargin += delta->left;
- (*pE).topMargin += delta->top;
-
- (*pE).hOrigin -= delta->left;
- (*pE).vOrigin -= delta->top;
-
- eTeUpdateCaretRect( hE );
- eTeAdjustScrollMax( hE );
- eTeCalibrate( hE );
- }
-
- void eTeNewView( eRec **hE, Rect *viewRect )
- {
- register eRec *pE = *hE;
- Rect delta;
-
- delta = *viewRect;
- delta.top -= (*pE).viewRect.top;
- delta.left -= (*pE).viewRect.left;
- delta.bottom -= (*pE).viewRect.bottom;
- delta.right -= (*pE).viewRect.right;
- (*pE).viewRect = *viewRect;
-
- eTeResize( hE, &delta );
- }
-
- /* eTeSetStyles also causes the display to be redrawn */
-
- void eTeSetStyles( eRec **hE, TextStyle *ts0, TextStyle *ts1 )
- {
- short height[2];
- FontInfo fontInfo[2];
- ChPos tmpPt;
- short bigger;
-
- (**hE).style[0] = *ts0;
- (**hE).style[1] = *ts1;
- (**hE).curStyle = NOSTYLE;
-
- /* Turn off cursor */
- eTePrepare( hE );
- eTeSetCaretState( hE, CARET_OFF );
-
- eTePrepareStyle( hE, 1 );
- GetFontInfo( &fontInfo[1] );
- height[1] = CharWidth( OPTION_SPACE );
-
- eTePrepareStyle( hE, 0 );
- GetFontInfo( &fontInfo[0] );
- height[0] = CharWidth( OPTION_SPACE );
-
- (**hE).spaceWidth = Max ( height[0], height[1] );
- /* calculate new tabstop based on new font/size */
- (**hE).tabWidth = (**hE).tabStops * (**hE).spaceWidth;
-
- height[0] = fontInfo[0].ascent + fontInfo[0].descent;
- height[1] = fontInfo[1].ascent + fontInfo[1].descent;
-
- bigger = height[1] > height[0] ? 1 : 0;
- (**hE).fontAscent = fontInfo[bigger].ascent;
- (**hE).caretHeight = height[bigger];
-
- /* Update caret values for new font */
- eTeUpdateCaretRect( hE );
- (**hE).maxRight = (**hE).caretRect.right;
-
- /*
- * Set the scale values for our scrollbars. Vertical scrolling is done by
- * lines; horizontal by widest character. First, move to top of panorama (but
- * don't redraw), then change the scale values. Finally, move back to original
- * position and redraw screen.
- */
- tmpPt = (**hE).position;
- eTeScroll( hE, -(**hE).position.h, -(**hE).position.v, FALSE );
- (**hE).hScale = Max( fontInfo[0].widMax, fontInfo[1].widMax );
- (**hE).vScale = (**hE).caretHeight + fontInfo[bigger].leading;
- eTeAdjustScrollMax( hE );
- eTeScrollTo( hE, tmpPt, FALSE );
- eTeRefresh( hE );
- }
-
- #ifdef include_obsolete_code
-
- void eTeSetFontNumber( eRec **hE, short aFontNumber )
- {
- Str255 fontName;
-
- GetFontName( aFontNumber, fontName );
- if ( fontName[0] == 0 )
- aFontNumber = 0; /* If font does not exist, then use the system font */
-
- /* Undo? */
- (**hE).fontNumber = aFontNumber;
- eTeFontChanged( hE );
- }
-
- void eTeSetFontName( eRec **hE, Str255 aFontName )
- {
- short fontNumber;
-
- GetFNum( aFontName, &fontNumber );
- eTeSetFontNumber( hE, ( fontNumber > 0 ) ? fontNumber : 0 );
- }
-
- void eTeSetFontSize( eRec **hE, short aFontSize )
- {
- /* Undo? */
- (**hE).fontSize = aFontSize;
- eTeFontChanged( hE );
- }
-
- #endif
-
- /* static -- 25Sep92 e for os_mac_Print.c */
- void eTeDrawLine( eRec **hE, ChPos beginPos, Point location )
- {
- register char c, *charPtr, *firstChar;
- register short count;
- long offset, instyle, inline, eol;
- short run, style;
- Point pt;
-
- HLock( (**hE).hText );
- MoveTo( location.h, location.v + (**hE).fontAscent );
-
- offset = *(*(**hE).hLines + beginPos.v) + beginPos.h;
- charPtr = *(**hE).hText + offset;
- eol = *(*(**hE).hLines + beginPos.v + 1);
- inline = eol - offset;
- run = eTeOffsetToRun( hE, offset );
- while( inline )
- { eTePrepareRun( hE, run );
- instyle = (*(**hE).hRuns)[++run] - offset;
- if( instyle > inline )
- instyle = inline;
- inline -= instyle;
- offset += instyle;
- firstChar = charPtr;
- count = 0;
- while ( instyle && ( c = *charPtr++ ) != RETURN ) /* 11Aug92 e was: instyle-- */
- { if ( c == TAB )
- { if ( count > 0 ) DrawText( firstChar, 0, count );
- GetPen( &pt );
- pt.h = eTeTabStop( hE, pt.h );
- MoveTo( pt.h, pt.v );
- firstChar = charPtr;
- count = 0;
- }
- else ++count;
- instyle -= 1; /* 11Aug92 e */
- }
- if ( count > 0 ) DrawText( firstChar, 0, count );
- }
- if( c != RETURN && *charPtr != '\0' ) DrawChar( 0xd7 );
- /* if( instyle == 0 && *charPtr != '\0' ) DrawChar( 0xd7 ); /* NG!? 11Aug92 e */
- HUnlock( (**hE).hText );
- }
-
- void eTeDraw( eRec **hE, Rect *area )
- {
- eRec *pE;
- short vFirst, vLast;
- ChPos startPos;
- Point location;
- Rect tRect;
- Boolean doCaret; /* 23Jul92 e */
-
- HLock( (Handle )hE );
- pE = *hE;
-
- if ( SectRect( area, &(*pE).viewRect, &tRect ) )
- {
- eTePrepare( hE );
-
- doCaret = ( ( ! (*pE).selActive ) && ( (*pE).caretState == CARET_ON ) );
- if( doCaret ) eTeSetCaretState( hE, CARET_OFF );
-
- vFirst = ( tRect.top - (*pE).topMargin + (*pE).vOrigin ) / (*pE).vScale;
- vLast = ( tRect.bottom + (*pE).vScale - (*pE).topMargin + (*pE).vOrigin - 1 )
- / (*pE).vScale;
-
- if ( vFirst < 0 )
- vFirst = 0;
- if ( vLast >= (*pE).bounds.v )
- vLast = (*pE).bounds.v - 1;
-
- EraseRect( &tRect );
-
- if ( vFirst < (*pE).bounds.v && vLast >= 0)
-
- { location.h = (*pE).leftMargin - (*pE).hOrigin;
- location.v = vFirst * (*pE).vScale + (*pE).topMargin - (*pE).vOrigin;
- startPos.h = 0;
-
- for ( startPos.v = vFirst;
- startPos.v <= vLast;
- location.v += (*pE).vScale, ++startPos.v )
- { eTeDrawLine( hE, startPos, location );
- }
- if ( (*pE).selActive )
- eTeHiliteRange( hE, (*pE).selStart, (*pE).selEnd ); /* may have munged it */
- else if( doCaret )
- eTeSetCaretState( hE, CARET_ON );
- }
- }
- HUnlock( (Handle )hE );
- }
-
- void eTeUpdate( eRec **hE )
- {
- Rect tempRect;
-
- eTePrepare( hE );
- tempRect = (**((**hE).macPort)->visRgn).rgnBBox;
- eTeDraw( hE, &tempRect );
- }
-
- #ifndef THINK_ARROWS
-
- static void eTeExtSelGuts( eRec **hE, ChPos chPos )
- {
- if( PTL( chPos ) < PTL( (**hE).caretChPos ) )
- { eTeHiliteRange( hE, chPos, (**hE).caretChPos );
- if( PTL( (**hE).caretChPos ) == PTL( (**hE).selStart ) )
- (**hE).selStart = chPos;
- else if( PTL( chPos ) >= PTL( (**hE).selStart ) )
- (**hE).selEnd = chPos;
- else
- { (**hE).selEnd = (**hE).selStart;
- (**hE).selStart = chPos;
- }
- }
- else if( PTL( chPos ) > PTL( (**hE).caretChPos ) )
- { eTeHiliteRange( hE, (**hE).caretChPos, chPos );
- if( PTL( (**hE).caretChPos ) == PTL( (**hE).selEnd ) )
- (**hE).selEnd = chPos;
- else if( PTL( chPos ) <= PTL( (**hE).selEnd ) )
- (**hE).selStart = chPos;
- else
- { (**hE).selStart = (**hE).selEnd;
- (**hE).selEnd = chPos;
- }
- }
- }
-
- #endif
-
- static void eTeEnsureChPos( eRec **hE, ChPos chPos )
- {
- if( PTL( chPos ) != PTL( (**hE).caretChPos ) )
- { (**hE).caretChPos = chPos;
- eTeUpdateCaretRect( hE );
- (**hE).maxRight = (**hE).caretRect.right;
- }
- }
-
- void eTeKey( eRec **hE, char theChar, Byte keyCode, short modifiers, short style )
- {
- char *charPtr;
- LineRec *linePtr;
- long offset;
- short eoln;
- ChPos chPos;
- char chars[ 255 ];
- Boolean shifted, optioned, commanded;
- Rect invalRect;
- long new;
- Point aPt;
-
- ObscureCursor();
- eTeSetCaretState( hE, CARET_OFF ); /* move up here 22Jul92 e */
-
- shifted = ( modifiers & shiftKey ) ? 1 : 0;
- optioned = ( modifiers & optionKey ) ? 1 : 0;
- commanded = ( modifiers & cmdKey ) ? 1 : 0;
-
- switch ( keyCode ) {
- case KeyF1:
- /* Undo */
- break;
- case KeyF2:
- eTeCut( hE );
- break;
- case KeyF3:
- eTeCopy( hE );
- break;
- case KeyF4:
- /* eTePaste( hE, style ); /* correct 3May92 e */
- eTePaste( hE, style ^ optioned ); /* for debugging 3May92 e */
- break;
- case KeyF5:
- case KeyF6:
- case KeyF7:
- case KeyF8:
- case KeyF9:
- case KeyF10:
- case KeyF11:
- case KeyF12:
- case KeyF13:
- case KeyF14:
- case KeyF15:
- /* DoFunctionKey( theChar, keyCode, modifiers ); */
- break;
-
- case KeyHome: /*** HOME ***/
- eTeScrollTo( hE, zeroPos, TRUE );
- break;
-
- case KeyEnd: /*** END ***/
- chPos.v = (**hE).bounds.v - (**hE).vSpan;
- if ( chPos.v < 0 )
- chPos.v = 0;
- chPos.h = (**hE).position.h;
- eTeScrollTo( hE, chPos, TRUE );
- break;
-
- case KeyPageUp: /*** PAGE UP ***/
- eTeDoVscroll( hE, inPageUp );
- eTeAdjustScrollMax( hE );
- break;
-
- case KeyPageDown: /*** PAGE DOWN ***/
- eTeDoVscroll( hE, inPageDown );
- eTeAdjustScrollMax( hE );
- break;
-
- case KeyDel: /*** DEL FWD ***/
- offset = eTeChPosToOffset( hE, (**hE).caretChPos );
- if ( (**hE).selActive )
- eTeDelete( hE );
- else if ( optioned ) { /* delete to end of line */
- /* 5Jul92 e */
- chPos = (**hE).caretChPos;
- linePtr = *(**hE).hLines;
- labelTryAgainK:
- chPos.h = linePtr[ chPos.v + 1 ] - linePtr[ chPos.v ];
- if ( chPos.v < (**hE).bounds.v - 1 )
- { --chPos.h;
- new = eTeChPosToOffset( hE, chPos );
- if( *(*(**hE).hText + new) != RETURN )
- { chPos.v++;
- goto labelTryAgainK;
- }
- if( new == offset )
- chPos.h++; /* delete the RETURN if its all there is */
- }
- eTeKillTo( hE, chPos );
- }
- else if ( *(*(**hE).hText + offset) != '\0' ) {
- /* 14Aug92 e for undo...
- eTeEdGuts( hE, EMPTY_PTR, 0L, *(*(**hE).hText + offset) == RETURN, TRUE, style );
- */
- eTeKillTo( hE, eTeOffsetToChPos( hE, offset + 1 ) ); /* optimize for Undo Typing */
- }
- break;
-
- default:
- MoveHHi( (Handle )(**hE).hLines );
- HLock( (Handle )(**hE).hLines );
- /* eTeSetCaretState( hE, CARET_OFF ); -- move above 22Jul92 e */
- linePtr = *(**hE).hLines;
- switch( theChar ) {
- case LEFT_ARROW: /*** LEFT ARROW ***/
- if ( (**hE).selActive && ! shifted )
- { /* if no shift key and there is a selection, remove it */
- eTeHiliteRange( hE, (**hE).selStart, (**hE).selEnd );
- chPos = (**hE).selEnd = (**hE).selStart;
- }
- #ifndef THINK_ARROWS
- else if( (**hE).selActive && optioned && commanded )
- { /* move chPos to start of selection if not there */
- chPos = (**hE).selStart;
- eTeEnsureChPos( hE, chPos );
- }
- #endif
- else
- { if ( shifted )
- { if ( ! (**hE).selActive )
- (**hE).selStart = (**hE).selEnd = (**hE).caretChPos;
- #ifdef THINK_ARROWS
- (**hE).caretChPos = (**hE).selStart;
- #endif
- }
- chPos = (**hE).caretChPos;
- if ( commanded )
- { chPos.h = 0; /* move to beginning of line */
- labelTryAgainL: /* added the rest 5Jul92 e */
- if ( chPos.v > 0 )
- { offset = eTeChPosToOffset( hE, chPos );
- if( *(*(**hE).hText + offset - 1) != RETURN )
- { chPos.v--;
- goto labelTryAgainL;
- }
- }
- }
- else if ( optioned )
- { /* move to start/end of previous word */
- offset = eTeChPosToOffset( hE, chPos );
- new = WordLimits( *(**hE).hText, offset, TRUE );
- if ( new == offset && offset != 0L )
- --new;
- chPos = eTeOffsetToChPos( hE, new );
- }
- else /* move to previous character position */
- chPos = eTeOffsetToChPos( hE, eTeChPosToOffset( hE, chPos ) - 1 );
- if ( shifted )
- {
- #ifdef THINK_ARROWS
- eTeHiliteRange( hE, chPos, (**hE).selStart );
- (**hE).selStart = chPos;
- #else
- eTeExtSelGuts( hE, chPos );
- #endif
- /* 30Apr92 e -- needed if newly active AND scrolling... */
- (**hE).selActive = ( PTL( (**hE).selStart ) != PTL( (**hE).selEnd ) );
- }
- }
- (**hE).caretChPos = chPos;
- eTeUpdateCaretRect( hE );
- (**hE).maxRight = (**hE).caretRect.right;
- eTeShowCaret( hE );
- break;
-
- case RIGHT_ARROW: /*** RIGHT ARROW ***/
- if ( (**hE).selActive && ! shifted )
- { /* if no shift key and there is a selection, remove it */
- eTeHiliteRange( hE, (**hE).selStart, (**hE).selEnd );
- chPos = (**hE).selStart = (**hE).selEnd;
- }
- #ifndef THINK_ARROWS
- else if( (**hE).selActive && optioned && commanded )
- { /* move chPos to end of selection if not there */
- chPos = (**hE).selEnd;
- eTeEnsureChPos( hE, chPos );
- }
- #endif
- else
- { if ( shifted )
- { if ( ! (**hE).selActive )
- (**hE).selStart = (**hE).selEnd = (**hE).caretChPos;
- #ifdef THINK_ARROWS
- (**hE).caretChPos = (**hE).selEnd;
- #endif
- }
- chPos = (**hE).caretChPos;
- if ( commanded )
- { /* move to end of line */
- labelTryAgainR:
- chPos.h = linePtr[ chPos.v + 1 ] - linePtr[ chPos.v ];
- if ( chPos.v < (**hE).bounds.v - 1 )
- { /* 5Jul92 e was: --chPos.h; */
- --chPos.h;
- offset = eTeChPosToOffset( hE, chPos );
- if( *(*(**hE).hText + offset) != RETURN )
- { chPos.v++;
- goto labelTryAgainR;
- }
- }
- }
- else if ( optioned )
- { /* move to start/end of next word */
- offset = eTeChPosToOffset( hE, chPos );
- new = WordLimits( *(**hE).hText, offset, FALSE );
- if ( new == offset && *(*(**hE).hText + offset) != '\0' )
- ++new;
- chPos = eTeOffsetToChPos( hE, new );
- }
- else /* move to previous character position */
- chPos = eTeOffsetToChPos( hE, eTeChPosToOffset( hE, chPos ) + 1 );
- if ( shifted )
- {
- #ifdef THINK_ARROWS
- eTeHiliteRange( hE, (**hE).selEnd, chPos );
- (**hE).selEnd = chPos;
- #else
- eTeExtSelGuts( hE, chPos );
- #endif
- /* 30Apr92 e -- needed if newly active AND scrolling... */
- (**hE).selActive = ( PTL( (**hE).selStart ) != PTL( (**hE).selEnd ) );
- }
- }
- (**hE).caretChPos = chPos;
- eTeUpdateCaretRect( hE );
- (**hE).maxRight = (**hE).caretRect.right;
- eTeShowCaret( hE );
- break;
-
- case UP_ARROW: /*** UP ARROW ***/
- if ( (**hE).selActive && ! shifted )
- { /* if no shift key and there is a selection, remove it */
- eTeHiliteRange( hE, (**hE).selStart, (**hE).selEnd );
- chPos = (**hE).selEnd = (**hE).selStart;
- }
- #ifndef THINK_ARROWS
- else if( (**hE).selActive && optioned && commanded )
- { /* move chPos to start of selection if not there */
- chPos = (**hE).selStart;
- eTeEnsureChPos( hE, chPos );
- }
- #endif
- else
- { if ( shifted )
- { if ( ! (**hE).selActive )
- (**hE).selStart = (**hE).selEnd = (**hE).caretChPos;
- #ifdef THINK_ARROWS
- else
- eTeEnsureChPos( hE, (**hE).selStart );
- #endif
- }
- chPos = (**hE).caretChPos;
- if ( commanded )
- chPos.h = chPos.v = 0; /* move to beginning of text */
- else if( optioned )
- { aPt.h = (**hE).maxRight;
- chPos.v -= (**hE).vSpan - (**hE).vOverlap; /* move up one page */
- if( chPos.v < 0 ) chPos.v = 0;
- chPos = eTePointHtoChPosH( hE, aPt, chPos );
- }
- else if ( chPos.v > 0 )
- { /* NG... [caretRect.top can be bogus!]
- aPt.h = (**hE).maxRight;
- aPt.v = (**hE).caretRect.top - (**hE).vScale;
- chPos = eTePointToChPos( hE, aPt );
- */
- aPt.h = (**hE).maxRight;
- chPos.v -= 1; /* move up one line */
- chPos = eTePointHtoChPosH( hE, aPt, chPos );
- }
- if ( shifted )
- {
- #ifdef THINK_ARROWS
- eTeHiliteRange( hE, chPos, (**hE).selStart );
- (**hE).selStart = chPos;
- #else
- eTeExtSelGuts( hE, chPos );
- #endif
- /* 30Apr92 e -- needed if newly active AND scrolling... */
- (**hE).selActive = ( PTL( (**hE).selStart ) != PTL( (**hE).selEnd ) );
- }
- }
- (**hE).caretChPos = chPos;
- eTeUpdateCaretRect( hE );
- eTeShowCaret( hE );
- break;
-
- case DOWN_ARROW: /*** DOWN ARROW ***/
- if ( (**hE).selActive && ! shifted )
- { /* if no shift key and there is a selection, remove it */
- eTeHiliteRange( hE, (**hE).selStart, (**hE).selEnd );
- chPos = (**hE).selStart = (**hE).selEnd;
- }
- #ifndef THINK_ARROWS
- else if( (**hE).selActive && optioned && commanded )
- { /* move chPos to end of selection if not there */
- chPos = (**hE).selEnd;
- eTeEnsureChPos( hE, chPos );
- }
- #endif
- else
- { if ( shifted )
- { if ( ! (**hE).selActive )
- (**hE).selStart = (**hE).selEnd = (**hE).caretChPos;
- #ifdef THINK_ARROWS
- else
- eTeEnsureChPos( hE, (**hE).selEnd );
- #endif
- }
- chPos = (**hE).caretChPos;
- if ( commanded )
- { /* move to end of text */
- chPos.v = (**hE).bounds.v - 1;
- chPos.h = linePtr[ chPos.v + 1 ] - linePtr[ chPos.v ];
- }
- else if( optioned )
- { aPt.h = (**hE).maxRight;
- if( chPos.v > (**hE).bounds.v - (**hE).vSpan + (**hE).vOverlap )
- chPos.v = (**hE).bounds.v - 1;
- else
- chPos.v += (**hE).vSpan - (**hE).vOverlap; /* move down one page */
- chPos = eTePointHtoChPosH( hE, aPt, chPos );
- }
- else if ( chPos.v < (**hE).bounds.v - 1 )
- { /* NG... [caretRect.top can be bogus!]
- aPt.h = (**hE).maxRight;
- aPt.v = (**hE).caretRect.top + (**hE).vScale;
- chPos = eTePointToChPos( hE, aPt );
- */
- aPt.h = (**hE).maxRight;
- chPos.v += 1; /* move down one line */
- chPos = eTePointHtoChPosH( hE, aPt, chPos );
- }
- if ( shifted )
- {
- #ifdef THINK_ARROWS
- eTeHiliteRange( hE, (**hE).selEnd, chPos );
- (**hE).selEnd = chPos;
- #else
- eTeExtSelGuts( hE, chPos );
- #endif
- /* 30Apr92 e -- needed if newly active AND scrolling... */
- (**hE).selActive = ( PTL( (**hE).selStart ) != PTL( (**hE).selEnd ) );
- }
- }
- (**hE).caretChPos = chPos;
- eTeUpdateCaretRect( hE );
- eTeShowCaret( hE );
- break;
-
- case DELETE: /*** DELETE ***/
- eTeDelete( hE );
- break;
-
- default: /*** TEXT ***/
- /* Undo? */
- if ( theChar == ENTER || theChar == RETURN ) {
- chars[ 0 ] = RETURN;
- offset = 1;
- #ifdef THINK_RETURN
- if ( (**hE).caretChPos.v > 0 ) {
- charPtr = *(**hE).hText + linePtr[ (**hE).caretChPos.v - 1 ];
- while ( *charPtr == TAB || *charPtr == SPACE ) {
- chars[ offset++ ] = *charPtr++;
- }
- }
- #endif
- }
- #ifdef CHAR8_OK
- else if ( theChar == TAB || (unsigned char)theChar >= SPACE )
- #else
- else if ( theChar == TAB || theChar >= SPACE )
- #endif
- {
- chars[0] = theChar;
- offset = 1;
- }
- else {
- break;
- }
- /* Insert character to right of cursor position */
- /* 14Aug92 e for undo...
- eTeEdGuts( hE, chars, (long )offset,
- ( chars[0] == RETURN ? TRUE : FALSE ), TRUE, style );
- */
- eTeKeyIns( hE, chars[0], style );
- /* (**hE).maxRight = (**hE).caretRect.right;
- -- done in eTeEdGuts -- 02Oct92 e */
- break;
- } /* END SWITCH ASCII CHARACTER */
-
- /* Update selection flag and turn cursor back on */
- (**hE).selActive = ( PTL( (**hE).selStart ) != PTL( (**hE).selEnd ) );
- eTeSetCaretState( hE, CARET_ON );
- HUnlock( (Handle )(**hE).hLines );
- break;
- }
- }
-
- void eTeClick( eRec **hE, Point hitPt, short modifierKeys, long when )
- {
- ChPos pos;
- Point newPt;
- Boolean didScroll = TRUE;
- long low, high, offset, start, end, anchorStart, anchorEnd;
- eRec *pE;
-
- HLock( (Handle )hE );
- pE = *hE;
-
- if ( ( hE == gLastViewHit ) &&
- ( ( when - gLastMouseUp.when ) < GetDblTime() ) &&
- ( Abs ( gLastMouseDown.where.h - hitPt.h ) < 3 ) &&
- ( Abs ( gLastMouseDown.where.v - hitPt.v ) < 3 ) )
- gClicks++;
- else
- gClicks = 1;
- gLastViewHit = hE;
-
- eTePrepare( hE );
-
- eTeSetCaretState( hE, CARET_OFF );
-
- if ( gClicks > 3 )
- gClicks = 3;
-
- if ( modifierKeys & shiftKey ) {
- gClicks = 1;
- if ( ! (*pE).selActive ) {
- (*pE).selStart = (*pE).caretChPos;
- (*pE).selEnd = (*pE).selStart;
- (*pE).selActive = TRUE;
- }
- start = eTeChPosToOffset( hE, (*pE).selStart );
- end = eTeChPosToOffset( hE, (*pE).selEnd );
- /* 24Jul92 e was...
- if( modifierKeys & optionKey )
- anchorStart = anchorEnd = end;
- else
- anchorStart = anchorEnd = start;
- s.b.... */
- if( eTeChPosToOffset( hE, (*pE).caretChPos ) == start )
- anchorStart = anchorEnd = (long )( ( modifierKeys & optionKey ) ? start : end );
- else
- anchorStart = anchorEnd = (long )( ( modifierKeys & optionKey ) ? end : start );
- /* since caretChPos is the active end 24Jul92 e */
- }
- else if ( (*pE).selActive ) {
- eTeHiliteRange( hE, (*pE).selStart, (*pE).selEnd );
- (*pE).selActive = FALSE;
- }
-
- /*
- * The DO-WHILE loop monitors the cursor while the mouse button is held down.
- * The selection is modified with changes in the cursor. NewPt is the new
- * mouse location, while hitPt contains the last position.
- */
- newPt = hitPt;
- do {
- if ( didScroll || PTL( newPt ) != PTL( hitPt ) ) {
- /* first time OR did scroll last loop OR mouse has moved */
- /* (didScroll == TRUE) causes this to execute first time */
- switch ( gClicks ) {
- case 3:
- pos = eTePointToChPos( hE, newPt );
- pos.h = 0;
- low = eTeChPosToOffset( hE, pos );
- if ( pos.v < (*pE).bounds.v - 1 ) {
- ++pos.v;
- pos.h = 0;
- }
- else {
- pos.h = (*(*pE).hLines)[ pos.v + 1 ] - (*(*pE).hLines)[ pos.v ];
- }
- high = eTeChPosToOffset( hE, pos );
- break;
-
- case 2:
- offset = eTeChPosToOffset( hE, eTePointToChPos( hE, newPt ) );
- low = WordLimits( *(*pE).hText, offset, TRUE );
- high = WordLimits( *(*pE).hText, offset, FALSE );
- break;
-
- default:
- low = eTeChPosToOffset( hE, eTePointToChPos( hE, newPt ) );
- high = low;
- break;
- }
- /*
- * Use selActive variable to tell us if this is the first time thru.
- * If so, then set our anchor points.
- * Otherwise we just update the selection around the anchors.
- */
- if ( ! (*pE).selActive ) {
- start = anchorStart = low;
- end = anchorEnd = high;
- eTeHiliteRange( hE, eTeOffsetToChPos( hE, low ), eTeOffsetToChPos(